package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

// go 语言中的接口就是python中的协议-鸭子类型
// 什么是鸭子类型？什么叫协议
// 看到一只鸟走起来像鸭子，游泳起来像鸭子，叫起来像鸭子，那么这只鸟就可以被称为鸭子
// 实际上就是实现了某个接口的所有方法后就可以认为实现了该接口
// 定义一个接口 类型通过实现一个接口的所有方法来实现该接口，无需专门显示证明，也就是没有implements关键字
type Animal interface {
	Eat()
	Run()
}

type Cat struct {
	Name string
	Sex  bool
}
type Dog struct {
	Name string
	Sex  bool
}

// 给cat结构体添加run方法
func (c Cat) Run() {
	fmt.Println(c.Name, "开始跑了")
}

// 给cat结构体添加eat方法
func (c Cat) Eat() {
	fmt.Println(c.Name, "开始吃了")
}
func (c Dog) Run() {
	fmt.Println(c.Name, "开始跑了")
}
func (c Dog) Eat() {
	fmt.Println(c.Name, "开始吃了")
}

// 一般用法
func main() {
	// 因为cat类型实现了animal接口，但我们无需显示声明此事，只要某类型实现了接口的所有方法go就会认为该类型实现了这个接口
	var a Animal = Cat{
		Name: "tom",
		Sex:  false,
	}

	// cat实际上是实现a这个接口中的方法
	// 但接口a中没有实例中的属性只有方法
	a.Eat()
	a.Run()
}

// 类似泛型的功能
func main2() {
	d := Dog{
		Name: "spack",
		Sex:  false,
	}
	myfunc(d)
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "ping",
		})
	})
	r.GET("/welcome", func(c *gin.Context) {
		// 第二个参数为默认值
		name := c.DefaultQuery("name", "guest")
		age := c.Query("age") // 是 c.Request.URl.Query().Get("name")
		c.String(http.StatusOK, "hello %s %s", name, age)
	})

	r.GET("/test", func(c *gin.Context) {
		c.Redirect(301, "http://www.baidu.com/")
	})
	r.Run()
}
func myfunc(a Animal) {
	a.Run()
	a.Eat()
}
